using Lzfy_Refund_Service.Models;
using Lzfy_Refund_Service.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Lzfy_Refund_Service.Controllers
{
    /// <summary>
    /// 退费流程控制器
    /// 处理跨数据库的退费业务流程，确保数据一致性
    /// </summary>
    [ApiController]
    [Route("api/[controller]")]
    [Authorize]
    public class RefundProcessController : ControllerBase
    {
        private readonly IRefundProcessService _refundProcessService;
        private readonly ILogger<RefundProcessController> _logger;

        public RefundProcessController(
            IRefundProcessService refundProcessService,
            ILogger<RefundProcessController> logger)
        {
            _refundProcessService = refundProcessService;
            _logger = logger;
        }

        /// <summary>
        /// 等待HIS退费处理
        /// 统一处理HIS数据库更新和验证码信息创建，确保数据一致性
        /// </summary>
        /// <param name="request">等待HIS退费请求</param>
        /// <returns>处理结果</returns>
        /// <response code="200">处理成功</response>
        /// <response code="400">请求参数无效</response>
        /// <response code="404">患者不存在</response>
        /// <response code="500">服务器内部错误</response>
        [HttpPost("wait-for-his-refund")]
        [ProducesResponseType(typeof(WaitForHisRefundResponse), 200)]
        [ProducesResponseType(typeof(WaitForHisRefundResponse), 400)]
        [ProducesResponseType(typeof(WaitForHisRefundResponse), 404)]
        [ProducesResponseType(typeof(WaitForHisRefundResponse), 500)]
        public async Task<ActionResult<WaitForHisRefundResponse>> WaitForHisRefund(
            [FromBody] WaitForHisRefundRequest request)
        {
            try
            {
                _logger.LogInformation("Received wait for HIS refund request for PatientId: {PatientId}", request?.PatientId);

                if (request == null)
                {
                    _logger.LogWarning("Request body is null");
                    return BadRequest(new WaitForHisRefundResponse
                    {
                        Success = false,
                        Message = "请求体不能为空"
                    });
                }

                // 验证模型
                if (!ModelState.IsValid)
                {
                    var errors = ModelState
                        .Where(x => x.Value?.Errors.Count > 0)
                        .SelectMany(x => x.Value!.Errors)
                        .Select(x => x.ErrorMessage)
                        .ToList();
                    
                    var errorMessage = string.Join("; ", errors);
                    _logger.LogWarning("Model validation failed: {Errors}", errorMessage);
                    
                    return BadRequest(new WaitForHisRefundResponse
                    {
                        Success = false,
                        Message = $"请求参数验证失败: {errorMessage}",
                        PatientId = request.PatientId
                    });
                }

                var response = await _refundProcessService.WaitForHisRefundAsync(request);

                if (response.Success)
                {
                    _logger.LogInformation("Wait for HIS refund completed successfully for PatientId: {PatientId}", request.PatientId);
                    return Ok(response);
                }
                else
                {
                    _logger.LogWarning("Wait for HIS refund failed for PatientId: {PatientId}, Message: {Message}", 
                        request.PatientId, response.Message);
                    
                    // 根据错误消息判断返回的状态码
                    if (response.Message.Contains("不存在"))
                    {
                        return NotFound(response);
                    }
                    else
                    {
                        return BadRequest(response);
                    }
                }
            }
            catch (ArgumentNullException ex)
            {
                _logger.LogError(ex, "Argument null exception in wait for HIS refund");
                return BadRequest(new WaitForHisRefundResponse
                {
                    Success = false,
                    Message = "请求参数不能为空"
                });
            }
            catch (ArgumentException ex)
            {
                _logger.LogError(ex, "Argument exception in wait for HIS refund");
                return BadRequest(new WaitForHisRefundResponse
                {
                    Success = false,
                    Message = ex.Message
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Unexpected error occurred while processing wait for HIS refund");
                return StatusCode(500, new WaitForHisRefundResponse
                {
                    Success = false,
                    Message = "服务器内部错误，请稍后重试",
                    Details = "系统已记录错误信息，请联系技术支持"
                });
            }
        }

        /// <summary>
        /// 手动回滚HIS退费密码日志
        /// 用于紧急情况下的数据修复
        /// </summary>
        /// <param name="patientId">患者ID</param>
        /// <param name="modifyTime">修改时间</param>
        /// <returns>回滚结果</returns>
        /// <response code="200">回滚成功</response>
        /// <response code="400">请求参数无效</response>
        /// <response code="500">服务器内部错误</response>
        [HttpPost("rollback-his-log")]
        [ProducesResponseType(typeof(object), 200)]
        [ProducesResponseType(typeof(object), 400)]
        [ProducesResponseType(typeof(object), 500)]
        public async Task<ActionResult> RollbackHisLog(
            [FromQuery] string patientId,
            [FromQuery] DateTime modifyTime)
        {
            try
            {
                if (string.IsNullOrEmpty(patientId))
                {
                    return BadRequest(new { success = false, message = "患者ID不能为空" });
                }

                _logger.LogInformation("Manual rollback HIS log request for PatientId: {PatientId}, ModifyTime: {ModifyTime}", 
                    patientId, modifyTime);

                var success = await _refundProcessService.RollbackHisRefundLogAsync(patientId, modifyTime);

                if (success)
                {
                    return Ok(new { success = true, message = "HIS退费密码日志回滚成功" });
                }
                else
                {
                    return Ok(new { success = false, message = "未找到匹配的日志记录" });
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error during manual rollback HIS log");
                return StatusCode(500, new { success = false, message = "回滚操作失败" });
            }
        }
    }
}